#ifndef _MEMORY_READER_H
#define _MEMORY_READER_H

#define MEMREAD_NO_ERROR		0
#define MEMREAD_LOADED_PREV		1
#define MEMREAD_NOT_LOADED		2
#define MEMREAD_READ_FAILED		3

namespace Process
{
	HANDLE* GetProcessesByName(__in LPSTR szProcname, __out DWORD* dwProcCount, __in bool fCaseSensitive = false);
};

class DLL_EXPORT CMemoryReader
{
#pragma region PrivateMembers
	HANDLE hProcess;
	template<typename T>
	T Read(unsigned dwAdress, BOOL fFixRet = FALSE);
	DWORD dwProcId;
	LPSTR szFileName;
	BOOL fInitialized;
	DWORD dwLastError;
#pragma endregion

public:
	CMemoryReader();
	CMemoryReader(__in HANDLE hProcess);
	~CMemoryReader();
	BOOL LoadFromProcessName(__in LPSTR szProcName);
	BOOL LoadFromClassName(__in LPSTR szClassName);
	BOOL LoadFromWindowName(__in LPSTR szWindowName);
	void SetErrorStream(std::basic_ostream<char, std::char_traits<char>>& ostr);

#pragma region ReadMembers
	UINT ReadUInt(DWORD dwAdress);
	INT ReadInt(DWORD dwAdress);
	ULONGLONG ReadUInt64(DWORD dwAdress);
	FLOAT ReadFloat(DWORD dwAdress);
	BOOL ReadString(DWORD dwAdress, __in __out LPSTR lpszDest, DWORD dwMaxLen);
	BYTE* ReadBytes(DWORD dwAdress, DWORD dwLen);
#pragma endregion

#pragma region MemoryReaderMembersAccessors
	LPCSTR GetProcessName() { return szFileName; }
	DWORD GetLastError() { return dwLastError; }
#pragma endregion
};

#endif